﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFontDatabase>
#include <QMdiSubWindow>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QFileInfo>
#include <QPrinter>
#include <QPrintDialog>
#include <QPrintPreviewDialog>
#include <QCloseEvent>
#include <QColorDialog>
#include <QTextCharFormat>
#include <QTextList>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{
    ui->mdiArea->setBackground(QBrush(Qt::white));
    initFontSize();
    initScrollBar();
    initWindowAction();

    connect(ui->mdiArea,&QMdiArea::subWindowActivated,this,&MainWindow::initWindowAction);

    initDocAction();

    actionGroup=new QActionGroup(this);
    actionGroup->setExclusive(true);
    mapper=new QSignalMapper(this);

    connect(ui->menu_W,&QMenu::aboutToShow,this,&MainWindow::addSubWindowAction);
    connect(mapper,SIGNAL(mapped(QWidget*)),this,SLOT(setActiveSubWindow(QWidget*)));

}

void MainWindow::addSubWindowAction()
{

    QList<QAction*> actionList=actionGroup->actions();
    if(!actionList.isEmpty())
    {
        for(QAction*action:actionList)
        {
            delete action;
        }
    }

    QList<QMdiSubWindow *> subWindowList=ui->mdiArea->subWindowList();
    if(!subWindowList.isEmpty())ui->menu_W->addSeparator();
    for(int i=0;i<subWindowList.count();i++)
    {
        QMdiSubWindow*subWindow=subWindowList[i];
        TextEdit*edit=qobject_cast<TextEdit*>(subWindow->widget());

        QString action_text=QString("%1 %2").arg(i+1).arg(edit->getDocWindowTitle());
        QAction*action =ui->menu_W->addAction(action_text);
        actionGroup->addAction(action);
        action->setCheckable(true);
        if(edit==activateWindow())action->setChecked(true);
        connect(action,SIGNAL(triggered(bool)),mapper,SLOT(map()));
        mapper->setMapping(action,subWindow);
    }
}

void MainWindow::setActiveSubWindow(QWidget *widget)
{
    if(widget) ui->mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow*>(widget));
}

void MainWindow::initFontSize()
{
    ui->sizeComboBox->clear();
    for(int fontSize:QFontDatabase::standardSizes())
    {
        ui->sizeComboBox->addItem(QString::number(fontSize));
    }

    QFont appFont=QApplication::font();
    int fontSize=appFont.pointSize();
    int sizeIndex=ui->sizeComboBox->findText(QString::number(fontSize));
    ui->sizeComboBox->setCurrentIndex(sizeIndex);
}

void MainWindow::initScrollBar()
{
    ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}

void MainWindow::initWindowAction()
{
    bool hasActiWindow=(activateWindow()!=nullptr);
    ui->saveAction->setEnabled(hasActiWindow);
    ui->saveAsAction->setEnabled(hasActiWindow);
    ui->printAction->setEnabled(hasActiWindow);
    ui->printViewAction->setEnabled(hasActiWindow);
    ui->undoAction->setEnabled(hasActiWindow);
    ui->redoAction->setEnabled(hasActiWindow);
    ui->pasteAction->setEnabled(hasActiWindow);
    ui->closeAction->setEnabled(hasActiWindow);
    ui->closeAllAction->setEnabled(hasActiWindow);
    ui->tittleAction->setEnabled(hasActiWindow);
    ui->cascadAction->setEnabled(hasActiWindow);
    ui->nextAction->setEnabled(hasActiWindow);
    ui->previousAction->setEnabled(hasActiWindow);
}

TextEdit *MainWindow::activateWindow()
{
    QMdiSubWindow*window=ui->mdiArea->activeSubWindow();
    if(window)
    {
        return qobject_cast<TextEdit*>(window->widget());

    }
    return nullptr;
}

void MainWindow::initDocAction()
{
    ui->cutAction->setEnabled(false);
    ui->copyAction->setEnabled(false);
    ui->colorAction->setEnabled(false);
    ui->boldAction->setEnabled(false);
    ui->italicAction->setEnabled(false);
    ui->underlineAction->setEnabled(false);
    ui->leftAlignAction->setEnabled(false);
    ui->centerAction->setEnabled(false);
    ui->rightAlignAction->setEnabled(false);
    ui->justifyAction->setEnabled(false);
}

QMdiSubWindow *MainWindow::findSubWindow(const QString &docName)
{
    QString filePath=QFileInfo(docName).canonicalFilePath();
    for(QMdiSubWindow*sub:ui->mdiArea->subWindowList())
    {
        TextEdit*edit=qobject_cast<TextEdit*>(sub->widget());
        if(edit->getDocFilePath()==filePath)
        {
            return sub;
        }
    }
    return nullptr;
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    ui->mdiArea->closeAllSubWindows();
    if(ui->mdiArea->currentSubWindow())
    {
        event->ignore();
    }
    else
    {
        event->accept();
    }
}



void MainWindow::on_newAction_triggered()
{
    TextEdit*edit=new TextEdit;
    ui->mdiArea->addSubWindow(edit);

    connect(edit,&TextEdit::copyAvailable,this,&MainWindow::setActionStatus);
    connect(edit,&TextEdit::selectionChanged,this,&MainWindow::setFuXuan);
    edit->initNewDoc();
    edit->show();
}


void MainWindow::setFuXuan()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        auto format=edit->currentCharFormat();
        ui->boldAction->setChecked(format.font().bold());
        ui->italicAction->setChecked(format.fontItalic());
        ui->underlineAction->setChecked(format.fontUnderline());
    }
}

void MainWindow::setActionStatus(bool b)
{
    ui->cutAction->setEnabled(b);
    ui->copyAction->setEnabled(b);
    ui->colorAction->setEnabled(b);
    ui->boldAction->setEnabled(b);
    ui->italicAction->setEnabled(b);
    ui->underlineAction->setEnabled(b);
    ui->leftAlignAction->setEnabled(b);
    ui->centerAction->setEnabled(b);
    ui->rightAlignAction->setEnabled(b);
    ui->justifyAction->setEnabled(b);
}

void MainWindow::on_openAction_triggered()
{
    QString docName=QFileDialog::getOpenFileName(this,"打开文档","../","所有文件(*.*);;文本文件(*.txt)");
    if(!docName.isEmpty())
    {
        QMdiSubWindow*sub=findSubWindow(docName);
        if(sub)
        {
            ui->mdiArea->setActiveSubWindow(sub);
            return;
        }
    }
    TextEdit*edit=new TextEdit;
    ui->mdiArea->addSubWindow(edit);
    connect(edit,&TextEdit::copyAvailable,this,&MainWindow::setActionStatus);

    if(edit->loadDoc(docName))
    {
        statusBar()->showMessage("文件已打卡",3000);
        edit->show();
    }
    else
    {
        edit->close();
    }
}

void MainWindow::on_saveAction_triggered()
{
    TextEdit* edit=activateWindow();
    if(edit)
    {
        if(edit->saveDoc())
        {
            statusBar()->showMessage("保存成功",3000);
        }
    }
}

void MainWindow::on_saveAsAction_triggered()
{
    TextEdit* edit=activateWindow();
    if(edit)
    {
        if(edit->saveAsDoc())
        {
            statusBar()->showMessage("保存成功",3000);
        }
    }
}

void MainWindow::on_printAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(!edit)return;

    QPrinter printer(QPrinter::HighResolution);


    QPrintDialog dialog(&printer,this);

    //下面两个必须同时才可生效
    //dialog.setOption(QAbstractPrintDialog::PrintSelection,true);
    //printer.setPrintRange(QPrinter::Selection);

    if(dialog.exec()==QPrintDialog::Accepted)
    {
        edit->print(&printer);
    }

}

void MainWindow::on_printViewAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(!edit)return;

    QPrinter printer;
    QPrintPreviewDialog perview(&printer,this);

    connect(&perview,&QPrintPreviewDialog::paintRequested,this,&MainWindow::paintPreview);//生成预览页面
    if(perview.exec()==QPrintPreviewDialog::Accepted)//点击打印
    {
        edit->print(&printer);
    }

}

void MainWindow::paintPreview(QPrinter *printer)
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->print(printer);
    }
}

void MainWindow::on_undoAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->undo();
    }
}


void MainWindow::on_redoAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->redo();
    }
}

void MainWindow::on_pasteAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->paste();
    }
}

void MainWindow::on_cutAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->cut();
    }
}

void MainWindow::on_copyAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->copy();
    }
}

void MainWindow::on_exitAction_triggered()
{
    close();
}

void MainWindow::on_closeAction_triggered()
{
    ui->mdiArea->closeActiveSubWindow();
}

void MainWindow::on_closeAllAction_triggered()
{
    ui->mdiArea->closeAllSubWindows();
}

void MainWindow::on_tittleAction_triggered()
{
    ui->mdiArea->tileSubWindows();
}

void MainWindow::on_cascadAction_triggered()
{
    ui->mdiArea->cascadeSubWindows();
}

void MainWindow::on_nextAction_triggered()
{
    ui->mdiArea->activateNextSubWindow();
}

void MainWindow::on_previousAction_triggered()
{
    ui->mdiArea->activatePreviousSubWindow();
}



void MainWindow::on_colorAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        QColor color=QColorDialog::getColor();
        if(!color.isValid())return ;

        QTextCharFormat format;
        format.setForeground(color);
        edit->mergeCurrentCharFormat(format);//合并
        //edit->setCurrentCharFormat(format);//设置

        QPixmap pixmap(16,16);
        pixmap.fill(color);
        ui->colorAction->setIcon(pixmap);

    }
}

void MainWindow::on_boldAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        bool isChecked=ui->boldAction->isChecked();

        QTextCharFormat format;
        format.setFontWeight(isChecked?QFont::Bold:QFont::Normal);
        edit->mergeCurrentCharFormat(format);//合并

    }
}

void MainWindow::on_italicAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        bool isChecked=ui->italicAction->isChecked();

        QTextCharFormat format;
        format.setFontItalic(isChecked);
        edit->mergeCurrentCharFormat(format);//合并

    }
}

void MainWindow::on_underlineAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        bool isChecked=ui->underlineAction->isChecked();

        QTextCharFormat format;
        format.setFontUnderline(isChecked);
        edit->mergeCurrentCharFormat(format);//合并

    }
}

void MainWindow::on_leftAlignAction_triggered()//软硬换行shift+enter
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->setAlignment(Qt::AlignLeft);
    }
}

void MainWindow::on_centerAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->setAlignment(Qt::AlignCenter);
    }
}

void MainWindow::on_rightAlignAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->setAlignment(Qt::AlignRight);
    }
}

void MainWindow::on_justifyAction_triggered()
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        edit->setAlignment(Qt::AlignJustify);
    }
}

void MainWindow::on_comboBox_activated(int index)
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        if(index==0)
        {
            QTextCursor cursor=edit->textCursor();

            cursor.beginEditBlock();
            QTextList*list=cursor.currentList();
            if(list)
            {
                list->remove(cursor.block());
                QTextBlockFormat blockFormat=cursor.blockFormat();
                blockFormat.setIndent(0);
                cursor.setBlockFormat(blockFormat);
            }

            cursor.endEditBlock();
            return;
        }
        QTextListFormat::Style style;
        switch(index)
        {
//            case 0:
//                style=QTextListFormat::ListStyleUndefined;
//                break;
        case 1:
            style=QTextListFormat::ListDisc;
            break;
        case 2:
            style=QTextListFormat::ListCircle;
            break;
        case 3:
            style=QTextListFormat::ListSquare;
            break;
        case 4:
            style=QTextListFormat::ListDecimal;
            break;
        case 5:
            style=QTextListFormat::ListLowerAlpha;
            break;
        case 6:
            style=QTextListFormat::ListUpperAlpha;
            break;
        case 7:
            style=QTextListFormat::ListLowerRoman;
            break;
        case 8:
            style=QTextListFormat::ListUpperRoman;
            break;
        default:
            style=QTextListFormat::ListStyleUndefined;
            break;
        }

        QTextCursor cursor=edit->textCursor();

        cursor.beginEditBlock();
        QTextBlockFormat blockFormat=cursor.blockFormat();
        QTextListFormat listFormat;
        QTextList*list=cursor.currentList();
        if(list)
        {
            listFormat=list->format();
            list->remove(cursor.block());

            blockFormat.setTextIndent(0);
            cursor.setBlockFormat(blockFormat);
        }
        listFormat.setStyle(style);
        cursor.createList(listFormat);



        cursor.endEditBlock();


    }
}



void MainWindow::on_fontComboBox_activated(const QString &arg1)
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        QTextCharFormat format;
        format.setFontFamily(arg1);
        edit->mergeCurrentCharFormat(format);
    }
}

void MainWindow::on_sizeComboBox_activated(const QString &arg1)
{
    TextEdit*edit=activateWindow();
    if(edit)
    {
        QTextCharFormat format;

        format.setFontPointSize(arg1.toInt());
        edit->mergeCurrentCharFormat(format);

    }
}

